/**
 * Copyright (c) 2006-2015, JGraph Ltd
 * Copyright (c) 2006-2015, Gaudenz Alder
 */
var mxLog =
{
  /**
	 * Class: mxLog
	 *
	 * A singleton class that implements a simple console.
	 *
	 * Variable: consoleName
	 *
	 * Specifies the name of the console window. Default is 'Console'.
	 */
  consoleName: 'Console',

  /**
	 * Variable: TRACE
	 *
	 * Specified if the output for <enter> and <leave> should be visible in the
	 * console. Default is false.
	 */
  TRACE: false,

  /**
	 * Variable: DEBUG
	 *
	 * Specifies if the output for <debug> should be visible in the console.
	 * Default is true.
	 */
  DEBUG: true,

  /**
	 * Variable: WARN
	 *
	 * Specifies if the output for <warn> should be visible in the console.
	 * Default is true.
	 */
  WARN: true,

  /**
	 * Variable: buffer
	 *
	 * Buffer for pre-initialized content.
	 */
  buffer: '',

  /**
	 * Function: init
	 *
	 * Initializes the DOM node for the console. This requires document.body to
	 * point to a non-null value. This is called from within <setVisible> if the
	 * log has not yet been initialized.
	 */
  init: function () {
    if (mxLog.window == null && document.body != null) {
      var title = mxLog.consoleName + ' - mxGraph ' + mxClient.VERSION

      // Creates a table that maintains the layout
      var table = document.createElement('table')
      table.setAttribute('width', '100%')
      table.setAttribute('height', '100%')

      var tbody = document.createElement('tbody')
      var tr = document.createElement('tr')
      var td = document.createElement('td')
      td.style.verticalAlign = 'top'

      // Adds the actual console as a textarea
      mxLog.textarea = document.createElement('textarea')
      mxLog.textarea.setAttribute('wrap', 'off')
      mxLog.textarea.setAttribute('readOnly', 'true')
      mxLog.textarea.style.height = '100%'
      mxLog.textarea.style.resize = 'none'
      mxLog.textarea.value = mxLog.buffer

      // Workaround for wrong width in standards mode
      if (mxClient.IS_NS && document.compatMode != 'BackCompat') {
        mxLog.textarea.style.width = '99%'
      } else {
        mxLog.textarea.style.width = '100%'
      }

      td.appendChild(mxLog.textarea)
      tr.appendChild(td)
      tbody.appendChild(tr)

      // Creates the container div
      tr = document.createElement('tr')
      mxLog.td = document.createElement('td')
      mxLog.td.style.verticalAlign = 'top'
      mxLog.td.setAttribute('height', '30px')

      tr.appendChild(mxLog.td)
      tbody.appendChild(tr)
      table.appendChild(tbody)

      // Adds various debugging buttons
      mxLog.addButton('Info', function (evt) {
        mxLog.info()
      })

      mxLog.addButton('DOM', function (evt) {
        var content = mxUtils.getInnerHtml(document.body)
        mxLog.debug(content)
      })

      mxLog.addButton('Trace', function (evt) {
        mxLog.TRACE = !mxLog.TRACE

        if (mxLog.TRACE) {
          mxLog.debug('Tracing enabled')
        } else {
          mxLog.debug('Tracing disabled')
        }
      })

      mxLog.addButton('Copy', function (evt) {
        try {
          mxUtils.copy(mxLog.textarea.value)
        } catch (err) {
          mxUtils.alert(err)
        }
      })

      mxLog.addButton('Show', function (evt) {
        try {
          mxUtils.popup(mxLog.textarea.value)
        } catch (err) {
          mxUtils.alert(err)
        }
      })

      mxLog.addButton('Clear', function (evt) {
        mxLog.textarea.value = ''
      })

      // Cross-browser code to get window size
      var h = 0
      var w = 0

      if (typeof (window.innerWidth) === 'number') {
        h = window.innerHeight
        w = window.innerWidth
      } else {
        h = (document.documentElement.clientHeight || document.body.clientHeight)
        w = document.body.clientWidth
      }

      mxLog.window = new mxWindow(title, table, Math.max(0, w - 320), Math.max(0, h - 210), 300, 160)
      mxLog.window.setMaximizable(true)
      mxLog.window.setScrollable(false)
      mxLog.window.setResizable(true)
      mxLog.window.setClosable(true)
      mxLog.window.destroyOnClose = false

      // Workaround for ignored textarea height in various setups
      if (((mxClient.IS_NS || mxClient.IS_IE) && !mxClient.IS_GC &&
				!mxClient.IS_SF && document.compatMode != 'BackCompat') ||
				document.documentMode == 11) {
        var elt = mxLog.window.getElement()

        var resizeHandler = function (sender, evt) {
          mxLog.textarea.style.height = Math.max(0, elt.offsetHeight - 70) + 'px'
        }

        mxLog.window.addListener(mxEvent.RESIZE_END, resizeHandler)
        mxLog.window.addListener(mxEvent.MAXIMIZE, resizeHandler)
        mxLog.window.addListener(mxEvent.NORMALIZE, resizeHandler)

        mxLog.textarea.style.height = '92px'
      }
    }
  },

  /**
	 * Function: info
	 *
	 * Writes the current navigator information to the console.
	 */
  info: function () {
    mxLog.writeln(mxUtils.toString(navigator))
  },

  /**
	 * Function: addButton
	 *
	 * Adds a button to the console using the given label and function.
	 */
  addButton: function (lab, funct) {
    var button = document.createElement('button')
    mxUtils.write(button, lab)
    mxEvent.addListener(button, 'click', funct)
    mxLog.td.appendChild(button)
  },

  /**
	 * Function: isVisible
	 *
	 * Returns true if the console is visible.
	 */
  isVisible: function () {
    if (mxLog.window != null) {
      return mxLog.window.isVisible()
    }

    return false
  },

  /**
	 * Function: show
	 *
	 * Shows the console.
	 */
  show: function () {
    mxLog.setVisible(true)
  },

  /**
	 * Function: setVisible
	 *
	 * Shows or hides the console.
	 */
  setVisible: function (visible) {
    if (mxLog.window == null) {
      mxLog.init()
    }

    if (mxLog.window != null) {
      mxLog.window.setVisible(visible)
    }
  },

  /**
	 * Function: enter
	 *
	 * Writes the specified string to the console
	 * if <TRACE> is true and returns the current
	 * time in milliseconds.
	 *
	 * Example:
	 *
	 * (code)
	 * mxLog.show();
	 * var t0 = mxLog.enter('Hello');
	 * // Do something
	 * mxLog.leave('World!', t0);
	 * (end)
	 */
  enter: function (string) {
    if (mxLog.TRACE) {
      mxLog.writeln('Entering ' + string)

      return new Date().getTime()
    }
  },

  /**
	 * Function: leave
	 *
	 * Writes the specified string to the console
	 * if <TRACE> is true and computes the difference
	 * between the current time and t0 in milliseconds.
	 * See <enter> for an example.
	 */
  leave: function (string, t0) {
    if (mxLog.TRACE) {
      var dt = (t0 != 0) ? ' (' + (new Date().getTime() - t0) + ' ms)' : ''
      mxLog.writeln('Leaving ' + string + dt)
    }
  },

  /**
	 * Function: debug
	 *
	 * Adds all arguments to the console if <DEBUG> is enabled.
	 *
	 * Example:
	 *
	 * (code)
	 * mxLog.show();
	 * mxLog.debug('Hello, World!');
	 * (end)
	 */
  debug: function () {
    if (mxLog.DEBUG) {
      mxLog.writeln.apply(this, arguments)
    }
  },

  /**
	 * Function: warn
	 *
	 * Adds all arguments to the console if <WARN> is enabled.
	 *
	 * Example:
	 *
	 * (code)
	 * mxLog.show();
	 * mxLog.warn('Hello, World!');
	 * (end)
	 */
  warn: function () {
    if (mxLog.WARN) {
      mxLog.writeln.apply(this, arguments)
    }
  },

  /**
	 * Function: write
	 *
	 * Adds the specified strings to the console.
	 */
  write: function () {
    var string = ''

    for (var i = 0; i < arguments.length; i++) {
      string += arguments[i]

      if (i < arguments.length - 1) {
        string += ' '
      }
    }

    if (mxLog.textarea != null) {
      mxLog.textarea.value = mxLog.textarea.value + string

      // Workaround for no update in Presto 2.5.22 (Opera 10.5)
      if (navigator.userAgent != null &&
				navigator.userAgent.indexOf('Presto/2.5') >= 0) {
        mxLog.textarea.style.visibility = 'hidden'
        mxLog.textarea.style.visibility = 'visible'
      }

      mxLog.textarea.scrollTop = mxLog.textarea.scrollHeight
    } else {
      mxLog.buffer += string
    }
  },

  /**
	 * Function: writeln
	 *
	 * Adds the specified strings to the console, appending a linefeed at the
	 * end of each string.
	 */
  writeln: function () {
    var string = ''

    for (var i = 0; i < arguments.length; i++) {
      string += arguments[i]

      if (i < arguments.length - 1) {
        string += ' '
      }
    }

    mxLog.write(string + '\n')
  }

}
